//Copyright 2008 Kristian Gundry And Rune Juhl-Petersen
//This file is part of Plain.

//Plain is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//any later version.

//Plain is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU Lesser General Public License for more details.

//You should have received a copy of the GNU Lesser General Public License
//along with Plain.  If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Text;


using NHibernate.Helper;
using NHibernate.Expression;
using NHibernate;
using System.Collections;

using Plain.Data;
using Plain;

namespace Plain.NHibernate
{
	public enum CompareOperator
	{
		AND, OR
	}

	/// <summary>
	/// Base class for DAO classes using NHibernate. This class will implement 
	/// the basic <see cref="IDao"/> interface so the concrete DAO classes don't have to.
	/// </summary>
	/// <typeparam name="T">The type of the entity that the DAO is responsible for</typeparam>
	public  class NHibernateDaoBase<T,TT> : IDao<T,TT>,ISearchableDao<T,TT> where T:IBusinessEntity<TT>
	{
		/// <summary>
		/// the type of the persistent type
		/// </summary>
		private System.Type persistentType = typeof(T);

		/// <summary>
		/// Generic get method for retrieving an entity from the database
		/// </summary>
		/// <param name="id">the id of the entity</param>
		/// <returns>the entity</returns>
		public T Get(TT id)
		{
			return Broker.Get<T>(id);
		}

		/// <summary>
		/// Retrieves all entities of a given type
		/// </summary>
		/// <returns>a generic IList</returns>
		public IList<T> GetAll()
		{
			return GetByCriteria();
		}

		/// <summary>
		/// Saves an entity to the database
		/// </summary>
		/// <param name="entity">the entity to save</param>
		/// <returns>the saved entity</returns>
		public TT Save(T entity)
		{
			Broker.Save(entity);
			return entity.Id;
		}
		
		/// <summary>
		/// Delete an entity from the database
		/// </summary>
		/// <param name="entity">the entity to delete</param>
		public void Delete(T entity)
		{
			Broker.Delete(entity);
		}
		
		/// <summary>
		/// Loads every instance of the requested type using the supplied <see cref="ICriterion" />.
		/// If no <see cref="ICriterion" /> is supplied, this behaves like <see cref="GetAll" />.
		/// </summary>
		protected IList<T> GetByCriteria(params ICriterion[] criterion)
		{
			ICriteria criteria = Broker.Session.CreateCriteria(persistentType);

			foreach (ICriterion criterium in criterion)
			{
				criteria.Add(criterium);
			}

			return criteria.List<T>() as List<T>;
		}
        
        /// <summary>
		/// Searches in the atabase as specified in the <see cref="Criteria"/>
		/// </summary>
		/// <param name="crit"></param>
		/// <returns></returns>
        //public IList<T> Search(Plain.Domain.Search.Criteria crit){
        //    NHibernateSearchParser parser = new NHibernateSearchParser();
        //    IQuery query = parser.ParseCriteria<T>(crit);
        //    return query.List<T>();
        //}

        public IList<T> Search(Plain.Search.Criteria crit, IDictionary<string, object> parameters, long start, long end, string sort) {
            NHibernateSearchParser parser = new NHibernateSearchParser(parameters);
            IQuery query = parser.ParseCriteria<T>(crit,sort);
            foreach (string s in parameters.Keys) {
                query.SetParameter(s, parameters[s]);
            }
            query.SetFirstResult((int)start);
            query.SetMaxResults((int)end);
            
            return query.List<T>();
        }
        public int GetCount(Plain.Search.Criteria crit,IDictionary<string,object> parameters) {

            return 0;
        }
	}
}
